package com.abhinav.designPatterns.abstractfactory;

public class AbstractFactoryDemo {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		AbstractFactory pf = FactoryMaker.getFactory("a");
		AbstractProductA productA = pf.createProductA();
		AbstractProductB productB = pf.createProductB();
	
		productA.operationA1();
		productA.operationA2();
		
		
	}

}

// AbstractProduct1
abstract class AbstractProductA {
	public abstract void operationA1();

	public abstract void operationA2();
}

// ConcreteProduct of AbstractProduct1
class ProductA1 extends AbstractProductA {

	public ProductA1(String arg) {
		System.out.println("Hello " + arg);
	}

	@Override
	public void operationA1() {
		System.out.println("ProductA1.operationA1");
	}

	@Override
	public void operationA2() {
		System.out.println("ProductA1.operationA2");
	}
}

// ConcreteProduct of Abstract Product1
class ProductA2 extends AbstractProductA {

	public ProductA2(String arg) {
		System.out.println("Hello " + arg);
	}

	@Override
	public void operationA1() {
		System.out.println("ProductA2.operationA1");
	}

	@Override
	public void operationA2() {
		System.out.println("ProductA2.operationA2");
	}
}

// AbstractProduct2
abstract class AbstractProductB {

}

// ConcreteProduct of AbstractProduct2
class ProductB1 extends AbstractProductB {
	public ProductB1(String arg) {
		System.out.println("Hello " + arg);
	}
}

// ConcreteProduct of AbstractProduct2
class ProductB2 extends AbstractProductB {
	public ProductB2(String arg) {
		System.out.println("Hello " + arg);
	}
}

// AbstractFactory
abstract class AbstractFactory {
	abstract AbstractProductA createProductA();

	abstract AbstractProductB createProductB();
}

// Concrete Factory1
class ConcreteFactory1 extends AbstractFactory {

	@Override
	AbstractProductA createProductA() {
		return new ProductA1("ProductA1");
	}

	@Override
	AbstractProductB createProductB() {
		return new ProductB1("ProductB1");
	}

}

// ConcreteFactory2
class ConcreteFactory2 extends AbstractFactory {

	@Override
	AbstractProductA createProductA() {
		return new ProductA2("ProductA2");
	}

	@Override
	AbstractProductB createProductB() {
		return new ProductB2("ProductB2");
	}

}

// Factory creator - an indirect way of instantiating the factories
class FactoryMaker {
	private static AbstractFactory pf = null;

	static AbstractFactory getFactory(String choice) {
		if (choice.equals("a")) {
			pf = new ConcreteFactory1();
		} else if (choice.equals("b")) {
			pf = new ConcreteFactory2();
		}
		return pf;
	}
}
